package com.duoduo.admin.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import com.duoduo.admin.api.dto.AppSmsDTO;
import com.duoduo.admin.entity.SysUser;
import com.duoduo.admin.repository.SysUserRepository;
import com.duoduo.common.core.constant.CacheConstants;
import com.duoduo.common.core.constant.SecurityConstants;
import com.duoduo.common.core.exception.ErrorCode;
import com.duoduo.common.core.exception.ErrorCodes;
import com.duoduo.common.core.util.MsgUtils;
import com.duoduo.common.core.util.R;

import cn.hutool.core.util.RandomUtil;
import jakarta.persistence.criteria.Predicate;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * 手机登录相关业务实现
 */
@Slf4j
@Service
@AllArgsConstructor
public class AppService {
	
	private final RedisTemplate redisTemplate;

	private final SysUserRepository sysUserRepository;

	//private final SmsClient smsClient;
	
	public R<Void> sendSmsCode(AppSmsDTO sms) {
		Object codeObj = redisTemplate.opsForValue().get(CacheConstants.DEFAULT_CODE_KEY + sms.getPhone());

		if (codeObj != null) {
			log.info("手机号验证码未过期:{}，{}", sms.getPhone(), codeObj);
			return R.failed(ErrorCode.SYS_APP_SMS_OFTEN);
		}
		// 校验手机号是否存在 sys_user 表
		if (sms.getExist()
				&& !sysUserRepository.exists((root, query, cb) -> {
					final List<Predicate> predicate = new ArrayList<Predicate>();
					predicate.add(cb.equal(root.get("phone"), sms.getPhone()));	
					final Predicate[] pre = new Predicate[predicate.size()];
					return query.where(predicate.toArray(pre)).getRestriction();
				})) {
			return R.failed(ErrorCode.SYS_APP_PHONE_UNREGISTERED);
		}

		String code = RandomUtil.randomNumbers(Integer.parseInt(SecurityConstants.CODE_SIZE));
		log.info("手机号生成验证码成功:{},{}", sms.getPhone(), code);
		redisTemplate.opsForValue().set(CacheConstants.DEFAULT_CODE_KEY + sms.getPhone(), code,
				SecurityConstants.CODE_TIME, TimeUnit.SECONDS);

		// 调用短信通道发送
		//this.smsClient.sendCode(code, sms.getPhone());
		return R.ok();
	}
	/**
	 * 校验验证码
	 * @param phone 手机号
	 * @param code 验证码
	 * @return
	 */
	public boolean check(String phone, String code) {
		Object codeObj = redisTemplate.opsForValue().get(CacheConstants.DEFAULT_CODE_KEY + phone);

		if (Objects.isNull(codeObj)) {
			return false;
		}
		return codeObj.equals(code);
	}

}
